package de.herzog.bbp.view.bean;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javafx.beans.property.ObjectProperty;
import de.herzog.bbp.model.AbstractModel;
import de.herzog.bbp.model.Halle;
import de.herzog.bbp.model.Klasse;
import de.herzog.bbp.model.Mannschaft;
import de.herzog.bbp.model.Spiel;

public class SpielBean extends AbstractBean implements Comparable<SpielBean> {

	private static SimpleDateFormat DF = new SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN);
	private static SimpleDateFormat WF = new SimpleDateFormat("EEE", Locale.GERMAN);

	private Spiel spiel;

	private ObjectProperty<Klasse> klasseProperty = new ObjectPropertyWithDirtyListener<>();
	private ObjectProperty<Integer> nummerProperty = new ObjectPropertyWithDirtyListener<>();;
	private ObjectProperty<String> wochentagProperty = new ObjectPropertyWithDirtyListener<>();
	private ObjectProperty<Date> datumProperty = new ObjectPropertyWithDirtyListener<>();
	private ObjectProperty<String> zeitProperty = new ObjectPropertyWithDirtyListener<>();
	private ObjectProperty<Mannschaft> heimProperty = new ObjectPropertyWithDirtyListener<>();
	private ObjectProperty<Mannschaft> gastProperty = new ObjectPropertyWithDirtyListener<>();
	private ObjectProperty<Halle> halleProperty = new ObjectPropertyWithDirtyListener<>();
	private ObjectProperty<String> schiriProperty = new ObjectPropertyWithDirtyListener<>();
	private ObjectProperty<String> errorProperty = new ObjectPropertyWithDirtyListener<>();

	public SpielBean(Spiel spiel) {
		this.spiel = spiel;
		klasseProperty.set(spiel.getKlasse());
		nummerProperty.set(spiel.getNummer());
		wochentagProperty.set(dateToWeekday(spiel.getDatum()));
		datumProperty.set(spiel.getDatum());
		zeitProperty.set(spiel.getZeit());
		heimProperty.set(spiel.getHeimMannschaft());
		gastProperty.set(spiel.getGastMannschaft());
		halleProperty.set(spiel.getHalle());
		schiriProperty.set(spiel.getSchiri());
		setDirty(false);

		klasseProperty.addListener((observable, oldValue, newValue) -> spiel.setKlasse(newValue));
		nummerProperty.addListener((observable, oldValue, newValue) -> spiel.setNummer(newValue));
		datumProperty.addListener((observable, oldValue, newValue) -> {
			spiel.setDatum(newValue);
			wochentagProperty.set(dateToWeekday(newValue));
		});
		zeitProperty.addListener((observable, oldValue, newValue) -> spiel.setZeit(newValue));
		heimProperty.addListener((observable, oldValue, newValue) -> spiel.setHeimMannschaft(newValue));
		gastProperty.addListener((observable, oldValue, newValue) -> spiel.setGastMannschaft(newValue));
		halleProperty.addListener((observable, oldValue, newValue) -> spiel.setHalle(newValue));
		schiriProperty.addListener((observable, oldValue, newValue) -> spiel.setSchiri(newValue));
	}

	public AbstractBean clone() {
		Spiel newSpiel = new Spiel();
		newSpiel.setKlasse(klasseProperty.get());
		newSpiel.setNummer(nummerProperty.get());
		newSpiel.setDatum(datumProperty.get());
		newSpiel.setZeit(zeitProperty.get());
		newSpiel.setHeimMannschaft(heimProperty.get());
		newSpiel.setGastMannschaft(gastProperty.get());
		newSpiel.setHalle(halleProperty.get());
		newSpiel.setSchiri(schiriProperty.get());
		SpielBean newSpielBean = new SpielBean(newSpiel);
		newSpielBean.setDirty(true);
		return newSpielBean;
	}

	public ObjectProperty<Klasse> klasseProperty() {
		return klasseProperty;
	}

	public ObjectProperty<Integer> nummerProperty() {
		return nummerProperty;
	}

	public ObjectProperty<String> wochentagProperty() {
		return wochentagProperty;
	}

	public ObjectProperty<Date> datumProperty() {
		return datumProperty;
	}

	public ObjectProperty<String> zeitProperty() {
		return zeitProperty;
	}

	public ObjectProperty<Mannschaft> heimProperty() {
		return heimProperty;
	}

	public ObjectProperty<Mannschaft> gastProperty() {
		return gastProperty;
	}

	public ObjectProperty<Halle> halleProperty() {
		return halleProperty;
	}

	public ObjectProperty<String> schiriProperty() {
		return schiriProperty;
	}

	public ObjectProperty<String> errorProperty() {
		return errorProperty;
	}

	@Override
	public List<AbstractModel> getDirtyModels() {
		List<AbstractModel> list = new ArrayList<>();
		if (isDirty()) {
			if (spiel.getKlasse() != spiel.getHeimMannschaft().getKlasse()) {
				spiel.getHeimMannschaft().setKlasse(spiel.getKlasse());
				list.add(spiel.getHeimMannschaft());
			}
			if (spiel.getKlasse() != spiel.getGastMannschaft().getKlasse()) {
				spiel.getGastMannschaft().setKlasse(spiel.getKlasse());
				list.add(spiel.getGastMannschaft());
			}
			if (spiel.getHeimMannschaft().getVerein() != spiel.getHalle().getVerein()) {
				spiel.getHalle().setVerein(spiel.getHeimMannschaft().getVerein());
				list.add(spiel.getHalle());
			}
			list.add(spiel);
		}
		return list;
	}

	public String getKlasse() {
		return klasseProperty().get().getName();
	}

	public Integer getNummer() {
		return nummerProperty().get();
	}

	public String getWochentag() {
		return wochentagProperty().get();
	}

	public Date getDatum() {
		return datumProperty().get();
	}

	public String getZeit() {
		return zeitProperty().get();
	}

	public String getHeimVerein() {
		return heimProperty().get().getVerein().getName();
	}

	public Integer getHeimNummer() {
		return heimProperty().get().getNummer();
	}

	public String getGastVerein() {
		return gastProperty().get().getVerein().getName();
	}

	public Integer getGastNummer() {
		return gastProperty().get().getNummer();
	}

	public Integer getHalleNummer() {
		return halleProperty().get().getNummer();
	}

	public String getSchiri() {
		return schiriProperty().get();
	}

	public String getError() {
		return errorProperty().get();
	}

	public void setError(String error) {
		errorProperty().set(error);
	}

	public void addError(String error) {
		String oldError = errorProperty().get();
		errorProperty().set(oldError == null ? error : oldError + ",  " + error);
	}

	public String getDatumString() {
		return dateToString(getDatum());
	}

	public static String dateToString(Date date) {
		return date == null ? "" : DF.format(date);
	}

	public static String dateToWeekday(Date date) {
		return date == null ? "" : WF.format(date);
	}

	public static Date stringToDate(String string) {
		try {
			return DF.parse(string);
		} catch (ParseException e) {
			return null;
		}
	}

	public Spiel getSpiel() {
		return spiel;
	}

	@Override
	public int compareTo(SpielBean otherSpielBean) {
		return getSpiel().compareTo(otherSpielBean.getSpiel());
	}
}
